package com.kmxd.ams.app.system;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kmxd.ams.client.system.ISysJobsSvc;
import com.kmxd.ams.core.common.constant.CacheConst;
import com.kmxd.ams.core.common.enums.JobsEnum;
import com.kmxd.ams.core.common.query.QueryGen;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.core.util.RedisUtils;
import com.kmxd.ams.infra.jobs.EsIndexJobs;
import com.kmxd.ams.infra.system.entity.SysJobs;
import com.kmxd.ams.infra.system.mapper.SysJobsMapper;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 定时任务配置 服务实现类
 *
 * @author ZuoLG
 * @since 2022-08-19
 */
@Service
@AllArgsConstructor
@Slf4j
@CacheConfig(cacheNames = CacheConst.CACHE_PREFIX_SYS_JOB)
public class SysJobsSvcImpl extends ServiceImpl<SysJobsMapper, SysJobs> implements ISysJobsSvc {

  private SysJobsMapper sysJobsMapper;
  @Autowired private RedisUtils redisUtils;

  @Cacheable(keyGenerator = "myKeyGenerator")
  @Override
  public Page<SysJobs> selectPage(Page reqPage, SysJobs req) {
    LambdaQueryWrapper<SysJobs> queryWrapper =
        QueryGen.init(new QueryWrapper<SysJobs>(), req).lambda();
    return sysJobsMapper.selectPage(reqPage, queryWrapper);
  }

  @Cacheable(keyGenerator = "myKeyGenerator")
  @Override
  public List<SysJobs> selectList(SysJobs req) {
    LambdaQueryWrapper<SysJobs> queryWrapper =
        QueryGen.init(new QueryWrapper<SysJobs>(), req).lambda();
    return sysJobsMapper.selectList(queryWrapper);
  }

  @Override
  public List<SysJobs> monitorInfo() {
    List<SysJobs> list = selectList(new SysJobs());
    list.forEach(
        item -> {
          Object startTime = redisUtils.get(CacheConst.REDIS_PREFIX + item.getTaskKey() + "_start");
          Object endTime = redisUtils.get(CacheConst.REDIS_PREFIX + item.getTaskKey() + "_end");
          item.setRunStartTime(ObjectUtil.isNotEmpty(startTime) ? startTime.toString() : null);
          item.setRunEndTime(ObjectUtil.isNotEmpty(endTime) ? endTime.toString() : null);
        });
    return list;
  }

  @CacheEvict(allEntries = true)
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void add(SysJobs req) {
    sysJobsMapper.insert(req);
    setJob(req);
  }

  @CacheEvict(allEntries = true)
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void edit(SysJobs req) {
    sysJobsMapper.updateById(req);
    setJob(req);
  }

  @CacheEvict(allEntries = true)
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void remove(String ids) {
    Set<Long> idList = IdUtil.split(ids);
    idList.forEach(
        item -> {
          SysJobs req = sysJobsMapper.selectById(item);
          req.setStatus(false);
          setJob(req);
          sysJobsMapper.deleteById(item);
        });
  }

  private void setJob(SysJobs req) {
     if (StrUtil.equalsIgnoreCase(req.getTaskKey(), JobsEnum.ES_INDEX_JOBS.getCode())) {
      EsIndexJobs job = SpringUtil.getBean(EsIndexJobs.class);
      if (req.getStatus()) {
        log.info("=======EsIndexJobs==============");
        job.setCron(req.getCron());
      } else {
        job.setCron(null);
      }
    } else if (StrUtil.equalsIgnoreCase(req.getTaskKey(), JobsEnum.OCR_JOBS.getCode())) {
      EsIndexJobs job = SpringUtil.getBean(EsIndexJobs.class);
      if (req.getStatus()) {
        log.info("=======EsIndexJobs==============");
        job.setCron(req.getCron());
      } else {
        job.setCron(null);
      }
    }
  }

  @Cacheable(keyGenerator = "myKeyGenerator")
  @Override
  public SysJobs view(Long id) {
    return sysJobsMapper.selectById(id);
  }

  @Override
  public SysJobs getJobsByKey(String key) {
    //    LambdaQueryWrapper<SysJobs> queryWrapper = Wrappers.lambdaQuery();
    //    queryWrapper.eq(SysJobs::getTaskKey, key);
    //    // 查询启用的
    //    queryWrapper.eq(SysJobs::getStatus, "1");
    List<SysJobs> list = selectList(new SysJobs());
    return list.stream()
        .filter(x -> x.getTaskKey().equals(key) && BooleanUtil.isTrue(x.getStatus()))
        .findFirst()
        .orElse(new SysJobs());
  }

  @CacheEvict(allEntries = true)
  @Override
  public void clearAllCache() {}
}
